package models

import (
	"database/sql"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"gorm.io/gorm"
	"hc_server/routers/response/merchantResponse"
	"time"
)

// Merchant 商户表
type Merchant struct {
	Model

	MerchantNo                string `json:"merchant_no" mapstructure:"merchant_no" gorm:"comment:'商户编号'"`
	MerchantRangeCode         int    `json:"merchant_range_code" mapstructure:"merchant_range_code" gorm:"comment:'MerchantRange经营范围表code'" `
	MerchantShopTypeID        int    `json:"merchant_shop_type_id" mapstructure:"merchant_shop_type_id" gorm:"comment:'MerchantShopType店铺类型表id'" `
	MerchantTypeID            int    `json:"merchant_type_id" mapstructure:"merchant_shop_type_id" gorm:"comment:'店铺类型表id';default:1" `
	ActivityID                int    `json:"activity_id" mapstructure:"activity_id" gorm:"comment:'activity活动类型表id'" `
	AgentID                   int    `json:"agent_id" mapstructure:"agent_id" gorm:"comment:'代理商id'"`
	SalesmenID                int    `json:"salesmen_id" gorm:"comment:'业务员id'"`
	MainMerchantId            int    `json:"main_merchant_id" gorm:"comment:'主店id'"`
	SpecialIndustryActivityId int    `json:"special_industry_activity_id" gorm:"comment:'特殊行业活动id'"`
	MerchantMobile            string `json:"merchant_mobile" mapstructure:"merchant_mobile"  gorm:"comment:'商户手机号'"`

	//商户信息
	MerchantName              string  `json:"merchant_name" mapstructure:"merchant_name" gorm:"comment:'商户名称 例 xxxx基地'"`
	MerchantFullName          string  `json:"merchant_full_name" mapstructure:"merchant_full_name" gorm:"comment:'商户全称 例 商户_李xx'"`
	MerchantLongitude         float64 `gorm:"column:merchant_longitude;type:decimal(10,7);comment:'经度'" mapstructure:"merchant_longitude" `
	MerchantLatitude          float64 `gorm:"column:merchant_latitude;type:decimal(10,7);comment:'纬度'" mapstructure:"merchant_latitude" `
	MerchantAddress           string  `json:"merchant_address" mapstructure:"merchant_address" gorm:"comment:'商户地址'"`
	MerchantAddressId         int     `json:"merchant_address_id" mapstructure:"merchant_address_id" gorm:"comment:'liancode表id'"`
	MerchantFrontPhoto        string  `json:"merchant_front_photo" mapstructure:"merchant_front_photo" gorm:"comment:'商户门脸照片'"`
	MerchantCheckstandPhoto   string  `json:"merchant_checkstand_photo" mapstructure:"merchant_checkstand_photo" gorm:"comment:'商户收银台照片'"`
	MerchantIndoorPhoto       string  `json:"merchant_indoor_photo" mapstructure:"merchant_indoor_photo" gorm:"comment:'经营场所照片'"`
	MerchantRelationCertPhoto string  `json:"merchant_relation_cert_photo" mapstructure:"merchant_relation_cert_photo" gorm:"comment:'总-门店关系说明函 总分店同个营业执照必填'"`

	//法人信息
	LegalPersonName                string `json:"legal_person_name" mapstructure:"legal_person_name" gorm:"comment:'法人姓名'"`
	LegalPersonIdcard              string `json:"legal_person_idcard" mapstructure:"legal_person_idcard" gorm:"comment:'法人身份证'"`
	LegalPersonIdcardPhotoFront    string `json:"legal_person_idcard_photo_front" mapstructure:"legal_person_idcard_photo_front" gorm:"comment:'法人身份证照片正面'"`
	LegalPersonIdcardPhotoBack     string `json:"legal_person_idcard_photo_back" mapstructure:"legal_person_idcard_photo_back" gorm:"comment:'法人身份证照片反面'"`
	LegalPersonIdcardHold          string `json:"legal_person_idcard_hold" mapstructure:"legal_person_idcard_hold" gorm:"comment:'手持身份证'"`
	LegalPersonIdcardValidityBegin string `json:"legal_person_idcard_validity_begin" mapstructure:"legal_person_idcard_validity_begin" gorm:"comment:'法人身份证有效期始'"`
	LegalPersonIdcardValidityEnd   string `json:"legal_person_idcard_validity_end" mapstructure:"legal_person_idcard_validity_end" gorm:"comment:'法人身份证有效期至'"`
	LegalContactType               string `json:"legal_contact_type" mapstructure:"legal_contact_type" gorm:"comment:'商户联系人类型 0-法人；1-委托人 ，小微，只能是0-法人'"`
	LegalContactName               string `json:"legal_contact_name" mapstructure:"legal_contact_name" gorm:"comment:'联系人姓名'"`
	LegalContactIdCardNo           string `json:"legal_contact_idcard_no" mapstructure:"legal_contact_idcard_no" gorm:"comment:'联系人身份证号'"`
	LegalContactMobile             string `json:"legal_contact_mobile" mapstructure:"legal_contact_mobile" gorm:"comment:'联系人手机号'"`

	LicensePhoto     string `json:"license_photo" mapstructure:"license_photo" gorm:"comment:'营业执照照片'"`
	LicenseName      string `json:"license_name" mapstructure:"license_name" gorm:"comment:'商户全称'"`
	LicenseCode      string `json:"license_code" mapstructure:"license_code" gorm:"comment:'营业执照号'"`
	LicenseStartDate string `json:"license_start_date" mapstructure:"license_start_date" gorm:"comment:'执照有效期起始日期'"`
	LicenseEndDate   string `json:"license_end_date" mapstructure:"license_end_date" gorm:"comment:'执照有效期结束日期'"`
	LicenseAddress   string `json:"license_address" mapstructure:"license_address" gorm:"comment:'执照地址'"`

	//结算信息
	SettleBankcardNo      string `json:"settle_bankcard_no" mapstructure:"settle_bankcard_no" gorm:"comment:'结算卡号'"`
	SettleBankPhone       string `json:"settle_bank_phone" mapstructure:"settle_bank_phone" gorm:"comment:'银行预留手机号'"`
	SettleName            string `json:"settle_name" mapstructure:"settle_name" gorm:"comment:'结算户名 法人对私结算：与法人姓名一致； 非法人对私结算：与非法人身份证信息一致； 法人对公结算：与营业执照注册名称一致'"`
	SettleIdcardNo        string `json:"settle_idcard_no" mapstructure:"settle_idcard_no" gorm:"comment:'结算人身份证号（非法人对私必填）'"`
	SettleIdcardStartDate string `json:"settle_idcard_start_date" mapstructure:"settle_idcard_start_date" gorm:"comment:'结算人身份证有效期起始日期（非法人对私必填） 格式：yyyy-MM-dd'"`
	SettleIdcardEndDate   string `json:"settle_idcard_end_date" mapstructure:"settle_idcard_end_date" gorm:"comment:'结算人身份证有效期结束日期（非法人对私必填） 格式：yyyy-MM-dd'"`
	SettleAccountType     int    `json:"settle_account_type" mapstructure:"settle_account_type" gorm:"comment:'结算账户类型：1-法人对私；2-非法人对私；3-法人对公；merchantType=1-小微，该参数必须为1-法人对私'"`
	LdSettleSubbranchCode string `json:"ld_settle_subbranch_code" mapstructure:"ld_settle_subbranch_code" gorm:"comment:'联动银行编码'"`
	SettleBankCardPhoto   string `json:"settle_bank_card_photo" mapstructure:"settle_bank_card_photo" gorm:"comment:'结算卡正面照'"`
	SettleIdcardFrontName string `json:"settle_idcard_front_name" mapstructure:"settle_idcard_front_name" gorm:"comment:'结算人身份证正面照'"`
	SettleIdcardBackName  string `json:"settle_idcard_back_name" mapstructure:"settle_idcard_back_name" gorm:"comment:'结算人身份证背面照'"`
	SettleAuthName        string `json:"settle_auth_name" mapstructure:"settle_auth_name" gorm:"comment:'结算授权书图片'"`

	AuditTime *time.Time `json:"audit_time" gorm:"comment:'审核时间'"`

	AuditStatus    int `json:"audit_status" mapstructure:"audit_status" gorm:"comment:'审核状态 0=未审核 1=审核通过 2=审核中 3=驳回'"`
	WechatStatus   int `json:"wechat_status" mapstructure:"wechat_status" gorm:"comment:'微信认证状态 0=未认证 1=认证未通过 2=微信认证'"`
	AliStatus      int `json:"ali_status" mapstructure:"ali_status" gorm:"comment:'支付宝认证状态 0=未认证 1=认证未通过 2=支付宝认证'"`
	BusinessStatus int `json:"business_status" mapstructure:"business_status" gorm:"comment:'营业状态 0=未营业 1=营业中'"`
	IndustryStatus int `json:"industry_status" mapstructure:"industry_status" gorm:"default:0;comment:'行业类型 0=默认行业 1=特殊行业'"`

	LDBusinessId string `json:"ld_business_id" mapstructure:"ld_business_id" gorm:"comment:'联动返回参数'"`
	LDMerchantId string `json:"ld_merchant_id" mapstructure:"ld_merchant_id" gorm:"comment:'联动返回商户id'"`
}

// MerchantExistByID 通过id判断是否存在
func MerchantExistByID(id int) (bool, error) {
	var mer Merchant
	err := db.Select("id").Where("id = ?", id).First(&mer).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.WithError(err).Errorf("此代理不存在: id:%d err:%v", id, err)
		return false, fmt.Errorf("此代理不存在")
	}

	return mer.ID > 0, nil
}

// MerchantExistByMobile 通过mobile判断是否存在
func MerchantExistByMobile(mobile string) (bool, error) {
	var mer Merchant
	err := db.Select("id").Where("merchant_mobile = ?", mobile).First(&mer).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.WithError(err).Errorf("此代理不存在: mobile:%s err:%v", mobile, err)
		return false, fmt.Errorf("此代理不存在")
	}

	return mer.ID > 0, nil
}

// MerchantByID 通过id获取商户信息
func MerchantByID(id int) (*Merchant, error) {
	var mer *Merchant
	err := db.Model(&Merchant{}).Where("id = ?", id).First(&mer).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.WithError(err).Errorf("此代理不存在: id:%d err:%v", id, err)
		return nil, fmt.Errorf("此代理不存在")
	}
	if mer.ID == 0 {
		logrus.WithError(err).Errorf("此代理不存在: id:%d err:%v", id, err)
		return nil, fmt.Errorf("此代理不存在")
	}

	return mer, nil
}

// MerchantInfoAdd 添加商户信息
func MerchantInfoAdd(mer *Merchant) (*Merchant, error) {
	err := db.Create(&mer).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		logrus.WithError(err).Errorf("添加商户失败: mer:%v err:%v", mer, err)
		return nil, fmt.Errorf("添加商户失败")
	}

	return mer, nil
}

func MerchantInfoUpdate(mapd map[string]interface{}, id interface{}) error {
	var mer *Merchant
	db.Model(&Merchant{}).Where("id = ?", id).Scan(&mer)
	if mer.ID == 0 {
		return errors.New("商户不存在")
	}
	db.Model(&Merchant{}).Where("id = ?", id).Updates(&mapd)
	return nil
}

// MerchantGetMerchantList 获取商户列表
func MerchantGetMerchantList(agentId, typed, pageNum, pageSize interface{}) map[string]interface{} {
	var (
		result          = make([]*merchantResponse.GetMerchantListResponse, 0)
		count           int64
		condition       string
		smallCount      int64 //小微
		personalCount   int64 //个人
		enterpriseCount int64 //企业
	)

	if cast.ToInt(typed) == 0 {
		condition = fmt.Sprintf("merchant_relations.agent_id = %d", agentId)
	} else {
		condition = fmt.Sprintf("FIND_IN_SET(%d, merchant_relations.relation) ", agentId)
	}

	db.Model(&MerchantRelation{}).
		Select("merchants.id, merchants.merchant_name AS title, s.name AS salesmen_name, " +
			"merchants.created_at AS created_time, merchants.audit_time AS audit_time, " +
			"merchants.audit_status AS audit_status, merchants.wechat_status AS wechat_status, " +
			"merchants.ali_status AS ali_status, COUNT(p.id) AS device_count," +
			"agents.agent_name").
		Joins("LEFT JOIN merchants ON merchants.id = merchant_relations.merchant_id").
		Joins("LEFT JOIN salesmens AS s ON s.id = merchants.salesmen_id").
		Joins("LEFT JOIN devices AS p ON p.merchant_id = merchants.id"). // 关联device表
		Joins("LEFT JOIN agents ON agents.id = merchants.agent_id ").
		Group("merchant_relations.merchant_id,merchant_relations.created_at"). // 根据所需字段分组
		Where(condition).
		Limit(cast.ToInt(pageSize)).
		Offset((cast.ToInt(pageNum) - 1) * cast.ToInt(pageSize)).
		Order("merchant_relations.created_at DESC").
		Scan(&result)

	db.Model(&MerchantRelation{}).
		Where(condition).
		Count(&count)

	db.Model(&MerchantRelation{}).Select("COUNT(merchants.id)").
		Joins("LEFT JOIN merchants ON merchants.id = merchant_relations.merchant_id AND merchants.merchant_type_id = 1").
		Where(condition).
		Count(&smallCount)

	db.Model(&MerchantRelation{}).Select("COUNT(merchants.id)").
		Joins("LEFT JOIN merchants ON merchants.id = merchant_relations.merchant_id AND merchants.merchant_type_id = 2").
		Where(condition).
		Count(&personalCount)

	db.Model(&MerchantRelation{}).Select("COUNT(merchants.id)").
		Joins("LEFT JOIN merchants ON merchants.id = merchant_relations.merchant_id AND merchants.merchant_type_id = 3").
		Where(condition).
		Count(&enterpriseCount)

	return map[string]interface{}{
		"result":     result,
		"count":      count,
		"small":      smallCount,
		"personal":   personalCount,
		"enterprise": enterpriseCount,
	}
}

// MerchantManagerSearch 商户管理列表搜索
func MerchantManagerSearch(conditions string, agentId, typed, pageNum, pageSize any) map[string]interface{} {
	var (
		result          = make([]*merchantResponse.GetMerchantListResponse, 0)
		count           int64
		smallCount      int64 //小微
		personalCount   int64 //个人
		enterpriseCount int64 //企业
		sqlCondition    string
	)

	if cast.ToInt(typed) == 0 {
		sqlCondition = fmt.Sprintf("merchant_relations.agent_id = %d", cast.ToInt(agentId))
	} else {
		sqlCondition = fmt.Sprintf("FIND_IN_SET(%d, merchant_relations.relation)", cast.ToInt(agentId))
	}

	db.Model(&MerchantRelation{}).
		Select("merchants.id, merchants.merchant_name AS title, s.name AS salesmen_name, " +
			"merchants.created_at AS submit_time, merchants.audit_time AS audit_time, " +
			"merchants.audit_status AS audit_status, merchants.wechat_status AS wechat_status, " +
			"merchants.ali_status AS ali_status, COUNT(p.id) AS device_count").
		InnerJoins(fmt.Sprintf("INNER JOIN merchants ON merchants.id = merchant_relations.merchant_id AND %s", conditions)).
		Joins("LEFT JOIN salesmens AS s ON s.id = merchants.salesmen_id").
		Joins("LEFT JOIN devices AS p ON p.merchant_id = merchants.id").       // 关联device表
		Group("merchant_relations.merchant_id,merchant_relations.created_at"). // 根据所需字段分组
		Where(sqlCondition).
		Limit(cast.ToInt(pageSize)).
		Offset((cast.ToInt(pageNum) - 1) * cast.ToInt(pageSize)).
		Order("merchant_relations.created_at DESC").
		Scan(&result)

	db.Model(&MerchantRelation{}).
		Select("COUNT(merchants.id)").
		InnerJoins(fmt.Sprintf(`INNER JOIN merchants ON merchants.id = merchant_relations.merchant_id AND ` + conditions)).
		Where(sqlCondition).
		Count(&count)

	db.Model(&MerchantRelation{}).
		Select("COUNT(merchants.id)").
		InnerJoins(fmt.Sprintf(`INNER JOIN merchants ON merchants.id = merchant_relations.merchant_id AND merchants.merchant_type_id = 1 AND ` + conditions)).
		Where(sqlCondition).
		Count(&smallCount)

	db.Model(&MerchantRelation{}).
		Select("COUNT(merchants.id)").
		InnerJoins(fmt.Sprintf(`INNER JOIN merchants ON merchants.id = merchant_relations.merchant_id AND merchants.merchant_type_id = 2 AND ` + conditions)).
		Where(sqlCondition).
		Count(&personalCount)

	db.Model(&MerchantRelation{}).
		Select("COUNT(merchants.id)").
		InnerJoins(fmt.Sprintf(`INNER JOIN merchants ON merchants.id = merchant_relations.merchant_id AND merchants.merchant_type_id = 3 AND ` + conditions)).
		Where(sqlCondition).
		Count(&enterpriseCount)

	return map[string]interface{}{
		"result":     result,
		"count":      count,
		"small":      smallCount,
		"personal":   personalCount,
		"enterprise": enterpriseCount,
	}
}

// MerchantGetMerchantInfo 获取商户基本信息
func MerchantGetMerchantInfo(id int) (*merchantResponse.GetMerchantInfoResponse, error) {
	var result *merchantResponse.GetMerchantInfoResponse
	err := db.Model(&Merchant{}).
		Select("merchants.merchant_name,merchants.merchant_full_name,merchants.merchant_no,"+
			"merchants.merchant_mobile,merchants.merchant_address AS merchant_shop_address,merchants.audit_status,"+
			"merchants.created_at AS submit_time,merchants.audit_time,merchant_types.info AS merchant_type,"+
			"merchant_shop_types.info AS merchant_shop_type,merchant_ranges.info AS merchant_range,agents.agent_name,"+
			"salesmens.name AS salesmen_name,activities.name AS activity_name,agents.agent_no").
		Joins("LEFT JOIN merchant_types ON merchant_types.id = merchants.merchant_type_id").
		Joins("LEFT JOIN merchant_shop_types ON merchant_shop_types.id = merchants.merchant_shop_type_id").
		Joins("LEFT JOIN merchant_ranges ON merchant_ranges.id = merchants.merchant_range_id").
		Joins("LEFT JOIN agents ON agents.id = merchants.agent_id").
		Joins("LEFT JOIN salesmens ON salesmens.id = merchants.salesmen_id").
		Joins("LEFT JOIN activities ON activities.id = merchants.activity_id").
		Where("merchants.id = ?", id).Scan(&result).Error
	if err != nil {
		logrus.WithError(err).Errorf("获取商户基本信息失败:err:%v,id:%v", err, id)
		return nil, errors.New("获取商户基本信息失败")
	}

	result.AgentNo = "P" + result.AgentNo
	result.MerchantNo = "M" + result.MerchantNo
	return result, nil
}

// MerchantGetMerchantListByMap 获取商户列表
func MerchantGetMerchantListByMap(condition string, selected string, pageNum, pageSize int, res interface{}) map[string]interface{} {
	var result map[string]interface{}
	var count int64
	db.Model(&Merchant{}).Where(condition).Count(&count)
	db.Model(&Merchant{}).Select(selected).Where(condition).Limit(pageSize).Offset((pageNum - 1) * pageSize).Scan(&res).Order("created_at DESC")
	result = make(map[string]interface{})
	result["count"] = count
	result["list"] = res

	return result
}

// MerchantGetMaxMerchantNo 获取当前最大的商户编号
func MerchantGetMaxMerchantNo() string {
	var maxMerchantNo sql.NullInt64
	db.Model(&Merchant{}).Select("MAX(CAST(merchant_no AS UNSIGNED)) AS max_merchant_no").Scan(&maxMerchantNo)
	// 检查 maxMerchantNo 是否为 NULL
	if maxMerchantNo.Valid {
		return cast.ToString(maxMerchantNo.Int64)
	} else {
		return "000000"
	}
}

// TransactionManagerMerchantList 获取所属商户交易信息
func TransactionManagerMerchantList(agentId, index, size, sort int) (map[string]interface{}, error) {
	var result = make([]*merchantResponse.GetMerchantTransactionListResponse, 0)
	var count int64
	var order string
	if sort == 2 {
		order = "SUM(mo.amount) ASC"
	} else if sort == 3 {
		order = "COUNT(DISTINCT mo.id) DESC"
	} else if sort == 4 {
		order = "COUNT(DISTINCT mo.id) ASC"
	} else {
		order = "SUM(mo.amount) DESC"
	}

	db.Select("merchants.id,merchants.merchant_name AS name,CONCAT('M',merchants.merchant_no) AS no,COUNT(DISTINCT mo.id) AS count,COALESCE(SUM(mo.amount), 0) AS amount").Model(&Merchant{}).
		Joins("LEFT JOIN merchant_orders AS mo ON mo.merchant_id = merchants.id").
		Group("merchants.id").
		Limit(cast.ToInt(size)).
		Offset((cast.ToInt(index)-1)*cast.ToInt(size)).
		Order(order).
		Where("merchants.agent_id = ?", agentId).Scan(&result)
	db.Model(&Merchant{}).
		Where("merchants.agent_id = ?", agentId).Count(&count)

	return map[string]interface{}{"data": result, "total": count}, nil
}
